1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package groovy;
20
21 import groovy.lang.Closure;
22 import groovy.lang.Reference;
23 import junit.framework.TestCase;
24 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
25
26 import java.math.BigDecimal;
27 import java.math.BigInteger;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.LinkedHashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.any;
37 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.collect;
38 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.each;
39 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.every;
40 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.findAll;
41 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.inject;
42 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.join;
43 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.max;
44 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.sort;
45
46
47
48
49
50 public class ClosureJavaIntegrationTest extends TestCase {
51 Map<String, Integer> zoo = new LinkedHashMap<String, Integer>();
52 List<String> animals = Arrays.asList("ant", "bear", "camel");
53
54 @Override
55 protected void setUp() throws Exception {
56 super.setUp();
57 zoo.put("Monkeys", 3);
58 zoo.put("Giraffe", 2);
59 zoo.put("Lions", 5);
60 }
61
62 public void testJoinListNonClosureCase() {
63 assertEquals(join(animals, ", "), "ant, bear, camel");
64 }
65
66 public void testEachList() {
67 final List<Integer> result = new ArrayList<Integer>();
68 each(animals, new Closure(null) {
69 public void doCall(String arg) {
70 result.add(arg.length());
71 }
72 });
73 assertEquals(Arrays.asList(3, 4, 5), result);
74 }
75
76 public void testEachMap() {
77 final List<String> result = new ArrayList<String>();
78 each(zoo, new Closure(null) {
79 public void doCall(String k, Integer v) {
80 result.add("k=" + k + ",v=" + v);
81 }
82 });
83 assertEquals(Arrays.asList("k=Monkeys,v=3", "k=Giraffe,v=2", "k=Lions,v=5" ), result);
84 }
85
86 public void testCollectList() {
87 assertEquals(Arrays.asList(3, 4, 5), collect(animals, new Closure<Integer>(null) {
88 public Integer doCall(String it) {
89 return it.length();
90 }
91 }));
92 }
93
94 public void testMaxMap() {
95 Map.Entry<String, Integer> lionEntry = null;
96 for (Map.Entry<String, Integer> entry : zoo.entrySet()) {
97 if (entry.getKey().equals("Lions")) lionEntry = entry;
98 }
99 assertEquals(lionEntry, max(zoo.entrySet(), new Closure<Integer>(null) {
100 public Integer doCall(Map.Entry<String, Integer> e) {
101 return e.getKey().length() * e.getValue();
102 }
103 }));
104 }
105
106 public void testSortMapKeys() {
107 assertEquals(Arrays.asList("Monkeys", "Lions", "Giraffe"), sort(zoo.keySet(), new Closure<Integer>(null) {
108 public Integer doCall(String a, String b) {
109 return -a.compareTo(b);
110 }
111 }));
112 assertEquals(Arrays.asList("Giraffe", "Lions", "Monkeys"), sort(zoo.keySet(), new Closure<Integer>(null) {
113 public Integer doCall(String a, String b) {
114 return a.compareTo(b);
115 }
116 }));
117 }
118
119 public void testAnyMap() {
120 assertTrue(any(zoo, new Closure<Boolean>(null) {
121 public Boolean doCall(String k, Integer v) {
122 return k.equals("Lions") && v == 5;
123 }
124 }));
125 }
126
127 public void testFindAllAndCurry() {
128 Map<String, Integer> expected = new HashMap<String, Integer>(zoo);
129 expected.remove("Lions");
130 Closure<Boolean> keyBiggerThan = new Closure<Boolean>(null) {
131 public Boolean doCall(Map.Entry<String, Integer> e, Integer size) {
132 return e.getKey().length() > size;
133 }
134 };
135 Closure<Boolean> keyBiggerThan6 = keyBiggerThan.rcurry(6);
136 assertEquals(expected, findAll(zoo, keyBiggerThan6));
137 }
138
139 public void testListArithmetic() {
140 List<List> numLists = new ArrayList<List>();
141 numLists.add(Arrays.asList(1, 2, 3));
142 numLists.add(Arrays.asList(10, 20, 30));
143 assertEquals(Arrays.asList(6, 60), collect(numLists, new Closure<Integer>(null) {
144 public Integer doCall(Integer a, Integer b, Integer c) {
145 return a + b + c;
146 }
147 }));
148 Closure<Integer> arithmeticClosure = new Closure<Integer>(null) {
149 public Integer doCall(Integer a, Integer b, Integer c) {
150 return a * b + c;
151 }
152 };
153 Closure<Integer> tensAndUnits = arithmeticClosure.curry(10);
154 assertEquals(35, (int) tensAndUnits.call(3, 5));
155 tensAndUnits = arithmeticClosure.ncurry(0, 10);
156 assertEquals(35, (int) tensAndUnits.call(3, 5));
157 tensAndUnits = arithmeticClosure.ncurry(1, 10);
158 assertEquals(35, (int) tensAndUnits.call(3, 5));
159 Closure<Integer> timesPlus5 = arithmeticClosure.rcurry(5);
160 assertEquals(35, (int) timesPlus5.call(15, 2));
161 timesPlus5 = arithmeticClosure.ncurry(2, 5);
162 assertEquals(35, (int) timesPlus5.call(15, 2));
163 }
164
165 public void testComposition() {
166 Closure<String> toUpperCase = new Closure<String>(null) {
167 public String doCall(String s) {
168 return s.toUpperCase();
169 }
170 };
171 Closure<Boolean> hasCapitalA = new Closure<Boolean>(null) {
172 public Boolean doCall(String s) {
173 return s.contains("A");
174 }
175 };
176 Closure<Boolean> hasA = toUpperCase.rightShift(hasCapitalA);
177 assertTrue(every(animals, hasA));
178 Closure<Boolean> alsoHasA = hasCapitalA.leftShift(toUpperCase);
179 assertTrue(every(animals, alsoHasA));
180 }
181
182 public void testTrampoline() {
183 final Reference<Closure<BigInteger>> ref = new Reference<Closure<BigInteger>>();
184 ref.set(new Closure<BigInteger>(null) {
185 public Object doCall(Integer n, BigInteger total) {
186 return n > 1 ? ref.get().trampoline(n - 1, total.multiply(BigInteger.valueOf(n))) : total;
187 }
188 }.trampoline());
189 Closure<BigInteger> factorial = new Closure<BigInteger>(null) {
190 public BigInteger doCall(Integer n) {
191 return ref.get().call(n, BigInteger.ONE);
192 }
193 };
194 assertEquals(BigInteger.valueOf(479001600), factorial.call(12));
195 }
196
197 public void testInject() {
198 Collection<Integer> c = Arrays.asList(2, 4, 5, 20);
199 Number initial = BigDecimal.ZERO;
200 Closure<? extends Number> closure = new Closure<BigDecimal>(c) {
201 BigDecimal doCall(BigDecimal total, Integer next) {
202 return total.add(BigDecimal.ONE.divide(new BigDecimal(next)));
203 }
204 };
205 assertTrue(DefaultTypeTransformation.compareEqual(BigDecimal.ONE, inject(c, initial, closure)));
206 }
207 }